<?php
/**
 * 部门控制器
 * 负责部门相关的CRUD操作
 * 支持完整的树形结构和权限继承功能
 */

declare(strict_types=1);

namespace app\controller\user;

use app\BaseController;
use think\facade\Db;
use think\facade\Request;
use think\response\Json;

class Department extends BaseController
{
    /**
     * 默认分页页码
     * @var int
     */
    protected $defaultPage = 1;

    /**
     * 默认每页数量
     * @var int
     */
    protected $defaultLimit = 15;

    /**
     * 最大每页数量
     * @var int
     */
    protected $maxLimit = 100;

    /**
     * 获取部门列表（树形结构）
     * GET /api/user/department/list
     */
    public function index(): Json
    {
        try {
            $param = Request::param();
            $needTree = $param['tree'] ?? true;
            
            // 获取所有部门信息，按sort字段降序和id字段升序排列
            $list = Db::name('department')
                ->where('status', '>', 0)
                ->order('sort desc,id asc')
                ->select()
                ->toArray();
            
            // 处理每个部门的负责人信息
            foreach ($list as &$dept) {
                if (!empty($dept['leader_ids'])) {
                    // 获取负责人的姓名
                    $adminIds = explode(',', $dept['leader_ids']);
                    $adminNames = Db::name('admin')
                        ->where('id', 'in', $adminIds)
                        ->where('status', '>=', 0)
                        ->column('name');
                    // 组合负责人姓名
                    $dept['leader'] = implode(',', $adminNames);
                } else {
                    $dept['leader'] = '';
                }
                
                // 统计部门下的员工数量
                $dept['user_count'] = Db::name('admin')
                    ->where('did', $dept['id'])
                    ->where('status', '>=', 0)
                    ->count();
            }
            
            if ($needTree) {
                // 生成树形结构
                $tree = $this->generateTree($list);
                return $this->success($tree, '获取部门树成功');
            } else {
                // 返回扁平结构
                return $this->success($list, '获取部门列表成功');
            }
        } catch (\Exception $e) {
            return $this->error('获取部门列表失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 查看单个部门详情
     * GET /api/user/department/{id}
     */
    public function read(): Json
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);
            
            if ($id <= 0) {
                return $this->paramError('部门ID不能为空');
            }
            
            $department = Db::name('department')
                ->where('id', $id)
                ->where('status', '>', 0)
                ->find();
            
            if (!$department) {
                return $this->error('部门不存在', 404);
            }
            
            // 获取部门负责人信息
            if (!empty($department['leader_ids'])) {
                $adminIds = explode(',', $department['leader_ids']);
                $leaders = Db::name('admin')
                    ->field('id, name, username')
                    ->where('id', 'in', $adminIds)
                    ->where('status', '>=', 0)
                    ->select()
                    ->toArray();
                $department['leaders'] = $leaders;
            } else {
                $department['leaders'] = [];
            }
            
            // 获取父部门信息
            if ($department['pid'] > 0) {
                $parentDept = Db::name('department')
                    ->field('id, title')
                    ->where('id', $department['pid'])
                    ->where('status', '>', 0)
                    ->find();
                $department['parent_name'] = $parentDept['title'] ?? '';
            } else {
                $department['parent_name'] = '顶级部门';
            }
            
            // 统计部门下的员工数量
            $department['user_count'] = Db::name('admin')
                ->where('did', $id)
                ->where('status', '>=', 0)
                ->count();
            
            // 获取子部门数量
            $department['children_count'] = Db::name('department')
                ->where('pid', $id)
                ->where('status', '>', 0)
                ->count();
            
            return $this->success($department, '获取部门信息成功');
        } catch (\Exception $e) {
            return $this->error('获取部门信息失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 创建部门
     * POST /api/user/department
     */
    public function save(): Json
    {
        try {
            $param = Request::param();
            
            // 数据验证
            if (empty($param['title'])) {
                return $this->paramError('部门名称不能为空');
            }
            
            // 检查父部门是否存在
            if (!empty($param['pid']) && $param['pid'] > 0) {
                $parentDept = Db::name('department')
                    ->where('id', $param['pid'])
                    ->where('status', '>', 0)
                    ->find();
                
                if (!$parentDept) {
                    return $this->paramError('父部门不存在');
                }
            }
            
            $data = [
                'title' => $param['title'],
                'pid' => (int)($param['pid'] ?? 0),
                'leader_ids' => $param['leader_ids'] ?? '',
                'phone' => $param['phone'] ?? '',
                'sort' => (int)($param['sort'] ?? 0),
                'remark' => $param['remark'] ?? '',
                'status' => (int)($param['status'] ?? 1),
                'create_time' => time(),
                'update_time' => time()
            ];
            
            // 检查部门名称是否已存在
            $existing = Db::name('department')
                ->where('title', $param['title'])
                ->where('pid', $data['pid'])
                ->where('status', '>', 0)
                ->find();
            
            if ($existing) {
                return $this->error('同级部门下已存在相同名称的部门', 422);
            }
            
            $deptId = Db::name('department')->insertGetId($data);
            
            return $this->created(['id' => $deptId], '创建部门成功');
        } catch (\Exception $e) {
            return $this->error('创建部门失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 更新部门
     * PUT /api/user/department/{id}
     */
    public function update(): Json
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);
            
            if ($id <= 0) {
                return $this->paramError('部门ID不能为空');
            }
            
            if (empty($param['title'])) {
                return $this->paramError('部门名称不能为空');
            }
            
            // 检查部门是否存在
            $department = Db::name('department')
                ->where('id', $id)
                ->where('status', '>', 0)
                ->find();
            
            if (!$department) {
                return $this->error('部门不存在', 404);
            }
            
            // 检查父部门是否存在
            if (!empty($param['pid']) && $param['pid'] > 0 && $param['pid'] != $department['pid']) {
                $parentDept = Db::name('department')
                    ->where('id', $param['pid'])
                    ->where('status', '>', 0)
                    ->find();
                
                if (!$parentDept) {
                    return $this->paramError('父部门不存在');
                }
            }
            
            $data = [
                'title' => $param['title'],
                'pid' => (int)($param['pid'] ?? $department['pid']),
                'leader_ids' => $param['leader_ids'] ?? $department['leader_ids'],
                'phone' => $param['phone'] ?? $department['phone'],
                'sort' => (int)($param['sort'] ?? $department['sort']),
                'remark' => $param['remark'] ?? $department['remark'],
                'status' => (int)($param['status'] ?? $department['status']),
                'update_time' => time()
            ];
            
            // 检查部门名称是否已存在（排除当前部门）
            $existing = Db::name('department')
                ->where('title', $param['title'])
                ->where('pid', $data['pid'])
                ->where('id', '<>', $id)
                ->where('status', '>', 0)
                ->find();
            
            if ($existing) {
                return $this->error('同级部门下已存在相同名称的部门', 422);
            }
            
            // 检查是否将父部门设置为自己或自己的子部门
            if ($data['pid'] != 0 && $data['pid'] != $department['pid']) {
                $childDepartments = $this->getDepartmentChildren($id);
                if ($data['pid'] == $id || in_array($data['pid'], $childDepartments)) {
                    return $this->error('上级部门不能是该部门本身或其下属部门', 422);
                }
            }
            
            Db::name('department')->where('id', $id)->update($data);
            
            return $this->updated(['id' => $id], '更新部门成功');
        } catch (\Exception $e) {
            return $this->error('更新部门失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 删除部门
     * DELETE /api/user/department/{id}
     */
    public function delete(): Json
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);
            
            if ($id <= 0) {
                return $this->paramError('部门ID不能为空');
            }
            
            // 检查部门是否存在
            $department = Db::name('department')
                ->where('id', $id)
                ->where('status', '>', 0)
                ->find();
            
            if (!$department) {
                return $this->error('部门不存在', 404);
            }
            
            // 检查是否有员工属于该部门
            $userCount = Db::name('admin')
                ->where('did', $id)
                ->where('status', '>=', 0)
                ->count();
            
            if ($userCount > 0) {
                return $this->error('该部门下有' . $userCount . '名员工，不能删除', 422);
            }
            
            // 检查是否有子部门
            $childCount = Db::name('department')
                ->where('pid', $id)
                ->where('status', '>', 0)
                ->count();
            
            if ($childCount > 0) {
                return $this->error('该部门下有' . $childCount . '个子部门，不能删除', 422);
            }
            
            Db::name('department')
                ->where('id', $id)
                ->update([
                    'status' => -1,
                    'update_time' => time()
                ]);
            
            return $this->deleted('删除部门成功');
        } catch (\Exception $e) {
            return $this->error('删除部门失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 获取部门树（用于下拉选择等场景）
     * GET /api/user/department/tree
     */
    public function tree(): Json
    {
        try {
            // 获取所有启用的部门信息
            $list = Db::name('department')
                ->field('id, title, pid')
                ->where('status', 1)
                ->order('sort desc, id asc')
                ->select()
                ->toArray();
            
            // 生成树形结构
            $tree = $this->generateTree($list);
            
            return $this->success($tree, '获取部门树成功');
        } catch (\Exception $e) {
            return $this->error('获取部门树失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 获取部门选项列表（用于下拉选择）
     * GET /api/user/department/options
     */
    public function options(): Json
    {
        try {
            // 默认获取所有启用的部门
            $type = Request::param('type', 0); // 0-全部, 1-内部部门, 2-外部律所
            
            $where = [];
            $where[] = ['status', '=', 1];
            
            // 根据类型筛选
            if ($type == 1) {
                $where[] = ['type', '=', 1];
            } elseif ($type == 2) {
                $where[] = ['type', '=', 2];
            }
            
            $list = Db::name('department')
                ->where($where)
                ->field('id, title, pid, type')
                ->order('sort desc, id asc')
                ->select()
                ->toArray();
            
            return $this->success($list, '获取部门选项成功');
        } catch (\Exception $e) {
            return $this->error('获取部门选项失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 获取启用的部门列表（用于设置）
     * GET /api/user/department/active-list
     */
    public function activeList(): Json
    {
        try {
            $list = Db::name('department')
                ->where('status', 1)
                ->field('id, title, pid')
                ->order('sort desc, id asc')
                ->select()
                ->toArray();
            
            return $this->success($list, '获取启用的部门列表成功');
        } catch (\Exception $e) {
            return $this->error('获取启用的部门列表失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 获取部门下的所有子部门（包括递归子部门）
     * GET /api/user/department/{id}/children
     */
    public function children(): Json
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);
            
            if ($id <= 0) {
                return $this->paramError('部门ID不能为空');
            }
            
            // 获取所有部门
            $departments = Db::name('department')
                ->field('id, title, pid')
                ->where('status', '>', 0)
                ->select()
                ->toArray();
            
            // 获取指定部门的所有子部门ID
            $childrenIds = [];
            $this->findChildren($departments, $id, $childrenIds);
            
            // 获取子部门详细信息
            if (!empty($childrenIds)) {
                $children = Db::name('department')
                    ->where('id', 'in', $childrenIds)
                    ->where('status', '>', 0)
                    ->select()
                    ->toArray();
            } else {
                $children = [];
            }
            
            return $this->success($children, '获取子部门成功');
        } catch (\Exception $e) {
            return $this->error('获取子部门失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 获取部门负责人
     * GET /api/user/department/{id}/leaders
     */
    public function leaders(): Json
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);
            
            if ($id <= 0) {
                return $this->paramError('部门ID不能为空');
            }
            
            // 获取部门信息
            $department = Db::name('department')
                ->field('leader_ids')
                ->where('id', $id)
                ->where('status', '>', 0)
                ->find();
            
            if (!$department) {
                return $this->error('部门不存在', 404);
            }
            
            // 获取负责人信息
            if (!empty($department['leader_ids'])) {
                $leaderIds = explode(',', $department['leader_ids']);
                $leaders = Db::name('admin')
                    ->field('id, name, username, mobile, email')
                    ->where('id', 'in', $leaderIds)
                    ->where('status', '>=', 0)
                    ->select()
                    ->toArray();
            } else {
                $leaders = [];
            }
            
            return $this->success($leaders, '获取部门负责人成功');
        } catch (\Exception $e) {
            return $this->error('获取部门负责人失败: ' . $e->getMessage(), 500);
        }
    }
    
    /**
     * 生成树形结构
     * @param array $flatArray 扁平数组数据
     * @param int $parentId 父节点ID，默认为0
     * @return array 树形结构数据
     */
    private function generateTree($flatArray, $parentId = 0)
    {
        $tree = [];
        foreach ($flatArray as $item) {
            if ($item['pid'] == $parentId) {
                $node = $item;
                $node['children'] = $this->generateTree($flatArray, $item['id']);
                $tree[] = $node;
            }
        }
        return $tree;
    }
    
    /**
     * 获取部门的所有子部门
     * @param int $departmentId 部门ID
     * @return array 子部门ID数组
     */
    private function getDepartmentChildren($departmentId)
    {
        $children = [];
        $departments = Db::name('department')->field('id,pid')->select()->toArray();
        
        $this->findChildren($departments, $departmentId, $children);
        
        return $children;
    }
    
    /**
     * 递归查找子部门
     * @param array $departments 所有部门数据
     * @param int $parentId 父部门ID
     * @param array &$children 子部门ID数组（引用传递）
     */
    private function findChildren($departments, $parentId, &$children)
    {
        foreach ($departments as $department) {
            if ($department['pid'] == $parentId) {
                $children[] = $department['id'];
                $this->findChildren($departments, $department['id'], $children);
            }
        }
    }
    
    // === 向后兼容方法 ===
    
    /**
     * 向后兼容：获取部门列表
     */
    public function list()
    {
        return $this->index();
    }
    
    /**
     * 向后兼容：查看部门详情
     */
    public function dept_view()
    {
        return $this->read();
    }
    
    /**
     * 向后兼容：创建部门
     */
    public function dept_add()
    {
        return $this->save();
    }
    
    /**
     * 向后兼容：编辑部门
     */
    public function dept_edit()
    {
        return $this->update();
    }
    
    /**
     * 向后兼容：删除部门
     */
    public function dept_del()
    {
        return $this->delete();
    }
    
    /**
     * 向后兼容：创建部门(store方法)
     */
    public function store()
    {
        return $this->save();
    }
    
    /**
     * 向后兼容：删除部门(destroy方法)
     */
    public function destroy()
    {
        return $this->delete();
    }
}